﻿package dk.flashnotes.fff.swfaddress {
	import dk.flashnotes.fff.utils.browser.EBrowsers;	
	
	import flash.system.System;	
	
	import dk.flashnotes.fff.utils.browser.BrowserUtils;	
	
	import flash.external.ExternalInterface;	
	
	import dk.flashnotes.fff.tree.parameters.NodeParameter;	
	import dk.flashnotes.fff.FFFBase;
	import dk.flashnotes.fff.tree.ETreeControlStates;
	import dk.flashnotes.fff.tree.TreeControl;
	import dk.flashnotes.fff.tree.TreeNode;

	import org.osflash.thunderbolt.Logger;

	import flash.events.Event;
	import flash.events.EventDispatcher;		

	/**
	 * @author josef
	 */
	public class SWFAddressControl extends EventDispatcher {

		private var _oTreeControl : TreeControl;
		private var _bLocked : Boolean = false;
		private var _sCurrentURL : String;
		private var _bSettingParameter : Boolean;
		private var _bParameterDisabled : Boolean=false;

		public function SWFAddressControl(oTreeControl : TreeControl) {
			
			_oTreeControl = oTreeControl;
			super();
			
			checkForParameterSupport();
			setup();
		}

		private function setup() : void {
			
			SWFAddress.onChange = onSWFAddressChange;
			
			SWFAddress.setTracker(null);
			
			_oTreeControl.oSH.registerStateInCallBack(ETreeControlStates.CHANGING_PAGE, onChangingPage);
			_oTreeControl.oSH.registerStateInCallBack(ETreeControlStates.READY, onReady);
		}

		private function onChangingPage() : void {
			lockControls();
		}

		private function onReady() : void {
			unlockControls();
		}

		private function unlockControls() : void {
			if (FFFBase.get_oInstance().bTracingEnabled) {
				Logger.info("UN LOCKING CONTORLS");
			}
			_bLocked = false;
		}

		private function lockControls() : void {
			if (FFFBase.get_oInstance().bTracingEnabled) {
				Logger.info("LOCKING CONTORLS");
			}
			_bLocked = true;
		}

		private function onSWFAddressChange(e : Event = null) : void {
			
			if(_bSettingParameter) {
				return;
			}
			
			if (!_bLocked) {
				
				if (FFFBase.get_oInstance().bTracingEnabled) {
					Logger.info("Logging path : " + _sCurrentURL);
				}
				
				// do url change
				_sCurrentURL = SWFAddress.getPath();
				dispatchEvent(new SWFAddressControlEvent(SWFAddressControlEvent.etURL_CHANGED));
			
				// check for parameter change
				Logger.info("dispatching parm change :: ");
				dispatchEvent(new SWFAddressControlEvent(SWFAddressControlEvent.etPARAMTER_CHANGED));
				
			} else {
				
				// if url changed when locked
				if (SWFAddress.getPath() != _sCurrentURL) {
					
					if (FFFBase.get_oInstance().bTracingEnabled) {
						Logger.info("ignoring url change to : " + SWFAddress.getPath());
					}
					
					dispatchEvent(new SWFAddressControlEvent(SWFAddressControlEvent.etURL_CHANGE_BLOCKED, SWFAddress.getPath()));
					
					SWFAddress.setHistory(false);
					SWFAddress.setValue(_sCurrentURL);
					SWFAddress.setHistory(true);
				}
			}
		}
		

		public function navigateToTreeNode(oTN : TreeNode) : void {
			
			if (oTN==null) {
				return;
			}
			
			var sAnchorUrl : String = oTN.oTNData.sUrl;
			
			if (get_sPqrameterString(oTN.oNodeParameterContol.a_oNPs)) {
				sAnchorUrl+=get_sPqrameterString(oTN.oNodeParameterContol.a_oNPs);
			}
			
			if (!_bLocked) {
				_sCurrentURL = sAnchorUrl;
				
				SWFAddress.setValue(sAnchorUrl);
			} else {
				dispatchEvent(new SWFAddressControlEvent(SWFAddressControlEvent.etURL_CHANGE_BLOCKED, sAnchorUrl));
			}
		}				public function navigateToUrl(sURL : String, sParmString : String="") : void {
			if (!_bLocked) {
				_sCurrentURL = sURL;
				SWFAddress.setValue(sURL +"?"+ sParmString);
			} else {
				dispatchEvent(new SWFAddressControlEvent(SWFAddressControlEvent.etURL_CHANGE_BLOCKED, sURL));
			}
		}						public function setBreadCrumb(a_oActiveBranchTreeNodes : Array) : void {
			SWFAddress.setTitle(get_sBreadCrumb(a_oActiveBranchTreeNodes));
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// parameter handeling
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function setParameters(a_oParameters : Array, bInitialParameterSet : Boolean = false) : void {
			if (!bInitialParameterSet && a_oParameters.length == 0) {
				return;
			}
			doParameterSet(get_sPqrameterString(a_oParameters));
		}

		private function doParameterSet(sParameterString : String) : void {
			
			if (sParameterString == null || _bParameterDisabled) {
				return;
			}
			
			_bSettingParameter = true;
			
			//SWFAddress.setHistory(false);
			SWFAddress.setValue(SWFAddress.getPath() + sParameterString);
			//SWFAddress.setHistory(true);
			
			_bSettingParameter = false;
		}

		public function get_sPqrameterString(a_oParameters : Array) : String {
			
			var sParameterString : String = "";
			a_oParameters.reverse();
			
			for each (var oNP : NodeParameter in a_oParameters) {
				if (oNP.bDisplayInURL && oNP.sValue!=null) {
					sParameterString += oNP.sKey + '=' + escape(oNP.sValue) + '&';
				}
			}
			
			if (sParameterString != "") {
				return '?' + sParameterString.substr(0, (sParameterString.length - 1));
			} else {
				return null;
			}
		}
		
		private function checkForParameterSupport() : void {
			
			// if not in browser
			if (!ExternalInterface.available) {
				_bParameterDisabled=true;
			}
			
			_bParameterDisabled=false;
			return;
			
			if (BrowserUtils.sBrowser==EBrowsers.SAFARI || BrowserUtils.sBrowser==EBrowsers.CHROME || BrowserUtils.sBrowser == EBrowsers.OPERA) {
				_bParameterDisabled=true;
			}
		}		

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// browser breadcrumb
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		private function get_sBreadCrumb(a_tnActiveBranch : Array) : String {
			
			var sReturn : String = "";
			var sSeperator : String = " : ";
			
			for (var i : int = 0;i < a_tnActiveBranch.length; i++) {
				var oTN : TreeNode = a_tnActiveBranch[i] as TreeNode;
				sReturn += oTN.oTNData.sTitle;
				
				if (i < (a_tnActiveBranch.length - 1)) {
					sReturn += sSeperator;
				}
			}
			return sReturn;
		}

		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
		// getters
		//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

		public function get sUrl() : String { 
			return _sCurrentURL; 
		}

		public function get bLocked() : Boolean {
			return _bLocked;
		}
	}
}
